#include <iostream>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <cstring>
#include <chrono>
#include <thread>

const char* cpp_out_shm_name = "cpp_out";      // C++ 输出共享内存名称
const char* python_out_shm_name = "python_out"; // Python 输出共享内存名称
const int SIZE = 1024;                   // 共享内存大小

// 等待共享内存创建
int waitForShm(const char* name) {
    int shm_fd;
    while (true) {
        shm_fd = shm_open(name, O_RDWR, 0666);
        if (shm_fd >= 0) {
            return shm_fd; // 返回共享内存文件描述符
        }
        std::cout << "等待共享内存创建..." << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1)); // 等待 1 秒后重试
    }
}

int main() {

    // 创建 C++ 的共享内存
    int cpp_out_fd = shm_open(cpp_out_shm_name, O_CREAT | O_RDWR, 0666);
    ftruncate(cpp_out_fd, SIZE);  // 调整共享内存大小
    void *cpp_out_shm = mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, cpp_out_fd, 0);  // 映射共享内存
    if (cpp_out_shm == MAP_FAILED) {
        std::cerr << "映射共享内存失败" << std::endl;
        return 1;
    }

    // 等待Python的共享内存
    int python_out_fd = waitForShm(python_out_shm_name);
    ftruncate(python_out_fd, SIZE); // 设置大小
    void* python_out_shm = mmap(0, 1024, PROT_READ, MAP_SHARED, python_out_fd, 0);


    while (true) {
        std::string command;
        std::cout << "输入命令: \n\t1: 输入\n\t2: 读取\n\t3: 退出\n-> ";
        std::cin >> command;

        // 往内存中写
        if (command == "1") {
            int data;
            std::cout << "\n输入数据: ";
            std::cin >> data;

            // 写入 cpp 共享内存
            memcpy(cpp_out_shm, &data, sizeof(data));
            std::cout << "C++: 数据已写入共享内存: " << data << "\n" << std::endl;
        }

        // 从内存中读取
        if (command == "2") {
            std::cout << "\n读取内存中的数据..." << std::endl;

            int retrieved_data;
            memcpy(&retrieved_data, python_out_shm, sizeof(retrieved_data));
            std::cout << "Python: 共享内存中的数据: " << retrieved_data << "\n" << std::endl;
        }

        // 退出
        if (command == "3") {
            std::cout << "退出..." << std::endl;
            break;
        }
    }

    // 清理
    munmap(python_out_shm, 1024);
    munmap(cpp_out_shm, 1024);
    close(python_out_fd);
    close(cpp_out_fd);
    shm_unlink(python_out_shm_name);
    shm_unlink(cpp_out_shm_name);

    return 0;
}